package com.atkxp.sys.controller;

import com.atkxp.sys.annotation.Log;
import com.atkxp.sys.entity.LoginUser;
import com.atkxp.sys.entity.Result;
import com.atkxp.sys.entity.Role;
import com.atkxp.sys.entity.User;
import com.atkxp.sys.enums.BusinessType;
import com.atkxp.sys.service.IRoleService;
import com.atkxp.sys.service.IUserService;
import com.atkxp.sys.utils.RedisCache;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author longhunpomie
 * @declaration
 * @email 3314028177@qq.com
 * @create 2023/9/20-17:52
 */
@RestController
@RequestMapping("/user/profile")
public class ProfileController {

    @Autowired
    private IUserService userService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;


    @GetMapping
    public Result<Map<String, Object>> profile()
    {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = ((LoginUser) authentication.getPrincipal());
        User user1 = loginUser.getUser();

        User user = userService.getUserById(user1.getId());
        Map map = new HashMap();
        map.put("user", user);
        List<Integer> idList = user.getRoleIdList();

        if(idList != null && idList.size() != 0) {
            LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(Role::getRoleId, idList);
            List<String> list = roleService.list(wrapper).stream().map(Role::getRoleDesc).collect(Collectors.toList());
            map.put("roleGroup", list);
        } else {
            map.put("roleGroup", "无角色");
        }

        return Result.success(map, "查询成功");
    }

    @PutMapping
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    public Result<?> updateProfile(@RequestBody User user) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        User oldUser = loginUser.getUser();

        oldUser.setEmail(user.getEmail());
        oldUser.setPhone(user.getPhone());
        oldUser.setSex(user.getSex());
        oldUser.setUsername(user.getUsername());

        loginUser.setUser(oldUser);

        //更新authentication
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        //更新缓存
        redisCache.setCacheObject(loginUser.getToken(), loginUser, 1800, TimeUnit.SECONDS);
        //更新数据库
        userService.updateById(oldUser);

        return Result.success("更新成功");
    }

    @PutMapping("/updatePwd")
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    public Result<?> updatePwd(String oldPassword, String newPassword) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String password = loginUser.getPassword();

        if(!passwordEncoder.matches(oldPassword, password)) {
            return Result.fail("修改失败！旧密码输入不正确！");
        }

        User user = loginUser.getUser();
        user.setPassword(passwordEncoder.encode(newPassword));
        loginUser.setUser(user);

        //更新authentication
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

        //更新缓存
        redisCache.setCacheObject(loginUser.getToken(), loginUser, 1800, TimeUnit.SECONDS);
        //更新数据库
        userService.updateById(user);

        return Result.success("更新成功！");
    }

    @PostMapping("/avatar")
    @Log(title = "用户头像", businessType = BusinessType.UPDATE)
    public Result<?> avatar(@RequestParam("avatarfile") MultipartFile file) {

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();

        List<String> imageType = new ArrayList<>();
        imageType.add("jpg");
        imageType.add("jpeg");
        imageType.add("png");
        imageType.add("bmp");
        imageType.add("gif");
        imageType.add("blob");

        // 获取文件名，带后缀
        String originalFilename = file.getOriginalFilename();
        // 获取文件的后缀格式
        String fileSuffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
        if (imageType.contains(fileSuffix)) {
            // 只有当满足图片格式时才进来，重新赋图片名，防止出现名称重复的情况
            String newFileName = UUID.randomUUID() + originalFilename;
            // 该方法返回的为当前项目的工作目录，即在哪个地方启动的java线程
            String dirPath = System.getProperty("user.dir");
            String path = File.separator + "profile" + "\\" + "avatar" + File.separator + newFileName;
            File destFile = new File(dirPath + path);
            if (!destFile.getParentFile().exists()) {
                destFile.getParentFile().mkdirs();
            }
            try {
                file.transferTo(destFile);
                Map map = new HashMap();
                map.put("imgUrl", path);

                User user = loginUser.getUser();
                user.setAvatar(path);
                loginUser.setUser(user);
                //更新authentication
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

                //更新缓存
                redisCache.setCacheObject(loginUser.getToken(), loginUser, 1800, TimeUnit.SECONDS);
                //更新数据库
                userService.updateById(user);

                // 将相对路径返回给前端
                return Result.success(map, "更新成功！");
            } catch (IOException e) {
                return Result.fail("上传失败！请重试");
            }
        } else {
            return Result.fail("文件只能为jpg，jpeg，png，gif和bmp");
        }

    }
}
